/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package paperlessflat.settings;

import com.sun.org.apache.xml.internal.serialize.OutputFormat;
import com.sun.org.apache.xml.internal.serialize.XMLSerializer;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Hashtable;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import paperlessflat.helper.Converter;
import paperlessflat.helper.PathHelper;

/**
 *
 * @author thunder2002
 */
public class SettingsManager {
    private static File settingFile = null;
    private static Hashtable<String, Object> settings = null;
    
    public static File getSettingFile() {
        if (settingFile == null) {
            settingFile = new File(PathHelper.getUserHomePath() + ".PaperlessFlat" + PathHelper.getFileSeparator() + "settings.xml");
            if (!settingFile.exists())
            {
                new File(settingFile.getParent()).mkdirs();
                try {
                    settingFile.createNewFile();
                } catch (IOException ex) {
                    Logger.getLogger(SettingsManager.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
        
        return settingFile;
    }
    protected static Hashtable<String, Object> getSettings() {
        if (settings == null) {
            settings = new Hashtable<String, Object>();
            if (getSettingFile() != null) {            
                DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

                try {
                    DocumentBuilder db = dbf.newDocumentBuilder();
                    Document doc = db.parse(getSettingFile());
                    Element root = doc.getDocumentElement();
                    NodeList nodes = root.getElementsByTagName("Setting");

                    String name;
                    Object value;
                    for (int i = 0; i < nodes.getLength(); ++i) {
                        Node node = nodes.item(i);
                        NamedNodeMap attributes = node.getAttributes();
                        name = attributes.getNamedItem("Name").getNodeValue();
                        value = attributes.getNamedItem("Value").getNodeValue();
                        settings.put(name, value);                        
                    }
                } catch (SAXException ex) {
                    Logger.getLogger(SettingsManager.class.getName()).log(Level.SEVERE, null, ex);
                } catch (IOException ex) {
                    Logger.getLogger(SettingsManager.class.getName()).log(Level.SEVERE, null, ex);
                } catch (ParserConfigurationException ex) {
                    Logger.getLogger(SettingsManager.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
        
        return settings;
    }
    
    private SettingsManager() {        
    }
    
    public static <T> T get(String settingName, Class<T> clazz) {        
        Object value = getSettings().get(settingName);
        //if (value == null)
        //    return null;
        
        return (T)Converter.convert(value, clazz);
    }
    public static void set(String settingName, Object obj) {
        getSettings().put(settingName, obj);
    }
    public static void save() {
        try {
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

            DocumentBuilder db = dbf.newDocumentBuilder();
            Document doc = db.newDocument();
            Element root = doc.createElement("Settings");
            doc.appendChild(root);

            for (String name : settings.keySet()) {
                Element setting = doc.createElement("Setting");
                setting.setAttribute("Name", name);
                setting.setAttribute("Value", settings.get(name).toString());
                root.appendChild(setting);
            }

            OutputFormat format = new OutputFormat(doc);
            format.setIndenting(true);
            
            XMLSerializer serializer = new XMLSerializer(new FileOutputStream(getSettingFile()), format);
            serializer.serialize(doc);
            
            settingFile = null;
        } catch (FileNotFoundException ex) {
            Logger.getLogger(SettingsManager.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(SettingsManager.class.getName()).log(Level.SEVERE, null, ex);
        } catch (ParserConfigurationException ex) {
            Logger.getLogger(SettingsManager.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}
